#include "utf8.h"

// 辅助函数：计算UTF-8字符的长度
int GetUTF8CharLength(const unsigned char *str, int pos)
{
    if ((str[pos] & 0x80) == 0x00)
        return 1; // 单字节字符
    if ((str[pos] & 0xE0) == 0xC0)
        return 2; // 双字节字符
    if ((str[pos] & 0xF0) == 0xE0)
        return 3; // 三字节字符
    if ((str[pos] & 0xF8) == 0xF0)
        return 4; // 四字节字符
    return 1;     // 非法字符，按单字节处理
}

// 函数用于找到UTF-8字符的起始位置
int FindStartOfUTF8Char(const unsigned char *str, int pos)
{
    while (pos > 0 && (str[pos] & 0xC0) == 0x80) {
        pos--;
    }
    return pos;
}

// 函数用于检查指定位置是否是一个有效的UTF-8字符起始位置
bool IsValidUTF8Start(const unsigned char *str, int pos)
{
    return (str[pos] & 0xC0) != 0x80;
}

// 辅助函数：删除指定位置的UTF-8字符
bool DeleteUTF8CharAtPosition(unsigned char *str, int pos, int len)
{
    if (pos < 0 || pos >= len) {
        return false; // 位置超出字符串范围
    }

    if (!IsValidUTF8Start(str, pos)) {
        return false; // 位置不是有效的UTF-8字符起始位置
    }

    int charLen = GetUTF8CharLength(str, pos);
    memmove(str + pos, str + pos + charLen, len - pos - charLen + 1);
    return true;
}

// 删除指定位置的UTF-8字符
bool DeleteUTF8Char(unsigned char *str, int pos)
{
    int len = strlen((char *)str);
    return DeleteUTF8CharAtPosition(str, pos, len);
}

// 删除指定位置前一个字符
bool DeletePrevUTF8Char(unsigned char *str, int pos)
{
    int len = strlen((char *)str);
    if (pos <= 0 || pos > len) {
        return false; // 位置超出范围
    }

    int start = FindStartOfUTF8Char(str, pos);
    if (start == 0) {
        return false; // 无法删除第一个字符
    }

    int prevStart = FindStartOfUTF8Char(str, start - 1);
    return DeleteUTF8CharAtPosition(str, prevStart, len);
}

// 删除指定位置后一个字符
bool DeleteNextUTF8Char(unsigned char *str, int pos)
{
    int len = strlen((char *)str);
    if (pos < 0 || pos >= len) {
        return false; // 位置超出范围
    }

    int start = FindStartOfUTF8Char(str, pos);
    int nextStart = start + GetUTF8CharLength(str, start);

    if (nextStart >= len) {
        return false; // 没有后一个字符
    }

    return DeleteUTF8CharAtPosition(str, nextStart, len);
}

// 找到指定位置的前一个有效UTF-8字符的起始位置
int FindValidStartPos(const unsigned char *str, int pos)
{
    while (pos > 0 && !IsValidUTF8Start(str, pos)) {
        pos--;
    }
    return pos;
}

// 找到指定位置的下一个有效UTF-8字符的起始位置
int FindValidEndPos(const unsigned char *str, int pos, int len)
{
    while (pos < len && !IsValidUTF8Start(str, pos)) {
        pos++;
    }
    return pos;
}

// 计算UTF-8字符串的显示长度
int CalculateDisplayLength(const unsigned char *str, int startPos, int endPos,
                           int len)
{
    int length = 0;
    int i = startPos;
    while (i < endPos) {
        int charLen = GetUTF8CharLength(str, i);
        length += (charLen >= 3) ? 2 : 1; // 中文字符占2个显示宽度
        i += charLen;
    }
    return length;
}

int FindEndPosForContainerWidth(const unsigned char *str, int startPos,
                                int containerWidth, int len)
{
    int currentWidth = 0;
    int i = startPos;

    while (i < len && currentWidth < containerWidth) {
        int charLen = GetUTF8CharLength(str, i);
        int charWidth = (charLen >= 3) ? 2 : 1; // 中文字符占2个显示宽度，英文字符占1个

        if (currentWidth + charWidth > containerWidth) {
            break; // 如果加上当前字符会超出容器宽度，则停止
        }

        currentWidth += charWidth;
        i += charLen;
    }

    return i; // 返回满足容器宽度的最大结束位置
}

int Test1()
{
    unsigned char str[] = "你好，Hello, 世界!"; // UTF-8编码的字符串
    int len = strlen((char *)str);              // 字符串的总长度

    int startPos = 3; // 假设起始位置是非法的（指向中文字符的中间字节）
    int endPos = 15;  // 假设结束位置是合法的

    // 调整起始位置和结束位置，确保它们是有效的UTF-8字符起始位置
    startPos = FindValidStartPos(str, startPos);
    endPos = FindValidEndPos(str, endPos, len);

    if (startPos >= endPos) {
        printf("Invalid range: startPos >= endPos\n");
        return 1;
    }

    int displayLength = CalculateDisplayLength(str, startPos, endPos, len);
    printf("The display length of the string from position %d to %d is: %d\n",
           startPos, endPos, displayLength);

    return 0;
}

int Test2()
{
    unsigned char str[] = "你好，世界!"; // UTF-8编码的字符串
    int pos = 3;                         // 假设我们要删除位置7的字符

    for (int i = 0; i < (int)sizeof(str); i++) {
        printf("%X- ", str[i]);
    }
    printf("str: %lld. end\n", sizeof(str));

    if (DeletePrevUTF8Char(str, pos)) {
        printf("%s\n", str);
    } else {
        printf("Invalid position or not a start of a UTF-8 character.\n");
    }

    for (int i = 0; i < (int)sizeof(str); i++) {
        printf("%X- ", str[i]);
    }
    printf("str: %lld. end\n", sizeof(str));
    return 0;
}

int Test3()
{
    unsigned char str[] = "你好，Hello, 世界!"; // UTF-8编码的字符串
    int len = strlen((char *)str);

    int startPos = 0;       // 起始位置
    int containerWidth = 7; // 容器宽度

    int endPos =
        FindEndPosForContainerWidth(str, startPos, containerWidth, len);
    printf("The end position for container width %d is: %d\n", containerWidth,
           endPos);

    // 打印满足容器宽度的字符串
    printf("Substring: ");
    for (int i = startPos; i < endPos; i++) {
        printf("%c", str[i]);
    }
    printf("\n");

    return 0;
}
